<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <style>
        .day,
        .hour,
        .min,
        .sec {
            display: inline-block;
            padding: 5px;
            vertical-align: middle;
            background-color: #6ff;
            color: #fff;
        }
    </style>
</head>

<body>
    <div id="app">
        <!-- 父组件/根组件使用了子组件count-down -->

        <!-- <count-down :time="100"></count-down>
        <count-down :time="1000"></count-down>
        <count-down :time="10000"></count-down> -->



        <!-- <count-down :time="10000000"></count-down> -->
        <count-down :time="10000000">
            <!-- 父组件对应插槽名称接收子组件传入的数据 -->
            <template v-slot:default="slotScope">
                <span v-if="slotScope.day>0">{{slotScope.beauty(slotScope.day)}}天</span>
                {{slotScope.beauty(slotScope.hour)}}:{{slotScope.beauty(slotScope.min)}}:{{slotScope.beauty(slotScope.sec)}}
            </template>
        </count-down>

        <!-- 可以根据子组件中给的的数据 ,自定义html结构 -->
        <!-- <count-down :time="10000000">
            <template v-slot:default="slotScope">
                <span class="day" v-if="slotScope.day>0">{{slotScope.beauty(slotScope.day)}}</span>天
                <span class="hour">{{slotScope.hour}}</span>:
                <span class="min">{{slotScope.min}}</span>:
                <span class="sec">{{slotScope.sec}}</span>
            </template>
        </count-down> -->


        <!-- scopeSlot 作用域插槽解构 -->
        <count-down :time="10000000">
            <template #default="{beauty,day,hour,min,sec}">
                <span class="day" v-if="day>0">{{beauty(day)}}</span>天
                <span class="hour">{{hour}}</span>:
                <span class="min">{{min}}</span>:
                <span class="sec">{{sec}}</span>
            </template>
        </count-down>



    </div>
</body>
<script>

    // 父组件如何如何传入数据 ?
    //     1. 在子组件的标签内作为属性传入 (prop传属性)
    //     2. 在子组件的标签对内作为内容传入  (插槽传内容)

    // 插槽中的内容也是父组件传入的, 可以使用父组件中的数据(data) 方法(methods) 计算属性



    // 插槽:  Vue 实现了一套内容分发的 API

    // 如何使用插槽 ? 父组件传, 子组件收
    // 1. 父组件传 => 父组件在使用子组件时, 在子组件的标签对内传入文本或html结构
    // 2. 子组件收 => 子组件使用 <slot></slot> 标签, 作为内容分发的出口 => 将内容输出到指定位置

    // 可以理解为 <slot></slot>  标签就是一个占位符, 当子组件渲染时, slot标签会被替换为传入的内容

    // 小技巧: 子组件中有$slots对象,用于存储父组件中传入的插槽内容

    // 命名插槽   父组件对应插槽名称传, 子组件对应插槽名称收
    // 1. 给<slot></slot> 标签添加name属性作为插槽名称,如果不设置name属性,默认name='default'
    // 2. 父组件传入插槽内容时,可以对应插槽名称传入 -> 替换对应name的<slot></slot> 标签,


    // 编译作用域
    // 插槽中的内容也是父组件传入的, 可以使用父组件中的数据(data) 方法(methods) 计算属性
    // 可以理解为
    // 1. 父组件先将插槽中的内容,编译一次 (得到虚拟DOM)
    // 2. 对应插槽名称传入到子组件 (虚拟DOM)
    // 3. 子组件接收到插槽内容,替换slot标签, => 子组件会将对应的虚拟DOM,解析为真实DOM

    // 结论: 父级模板里的所有内容都是在父级作用域中编译的；子模板里的所有内容都是在子作用域中编译的。

    // 作用域插槽
    // 作用: 让插槽内容能够访问子组件中才有的数据

    // 1. 子组件 在<slot></slot>标签中按需暴露数据, 对应属性名暴露数据  => 子组件内部将所有的数据整合到一起,得到对应属性的对象
    // <slot :day="day" :hour="hour" :min="min" :sec="sec"></slot>  => {day:xxx,hour,min,sec}

    // 2. 父组件传入插槽内容时,对应插槽名可以接收数据(对象) 
    // <template v-slot:default="slotScope"></template>   => slotScope= {day:xxx,hour,min,sec}

    // 3. 父组件的插槽内容就可以使用子组件中暴露的数据



    // 全局组件
    Vue.component("count-down", {
        props: ["time"],
        data: function () {
            return {
                countTime: this.time,  //倒计时的时间(s)
                timer: null,
            }
        },
        template: `  <div class="count-down">
            <slot :day="day" :hour="hour" :min="min" :sec="sec" :beauty="beauty"><span v-if="day>0">{{beauty(day)}}天</span> {{beauty(hour)}}:{{beauty(min)}}:{{beauty(sec)}}</slot>
        </div>`,
        methods: {
            beauty(num) {
                return num < 10 ? "0" + num : num;
            },
            countDownHandler() {
                clearInterval(this.timer);
                this.timer = setInterval(() => {
                    this.countTime--;
                }, 1000)
            }
        },
        computed: {
            // 将倒计时的时间换算为天时分秒
            day: function () {
                return parseInt(this.countTime / (24 * 60 * 60));
            },
            hour: function () {
                // 总的时间 % 一天的时间 =>  不满一天的时间
                // 不满一天的时间 / 一小时
                return parseInt(this.countTime % (24 * 60 * 60) / (60 * 60))
            },
            min: function () {
                // 不满一小时 / 一分钟
                return parseInt(this.countTime % (60 * 60) / 60);
            },
            sec: function () {
                // 不满一小时 / 一分钟
                return this.countTime % 60;
            },
        },

        mounted() {
            this.countDownHandler();
            console.log("子组件count-down:mounted", this);
            console.log("子组件count-down:mounted", this.$scopedSlots.default);
        },
    })


    // 根组件
    var app = new Vue({
        el: "#app",
        data: {
            count: 1,
        },

    })








</script>

</html>